package com.shop.shopserver.websocket;

import com.shop.shopcommon.properties.WebSocketProperties;
import com.shop.shopcommon.utils.SpringContextUtil;
import com.shop.shoppojo.entity.HotSearch;
import com.shop.shopserver.mapper.HotSearchMapper;
import com.shop.shopserver.service.HotSearchService;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.scheduling.annotation.Scheduled;
import org.springframework.stereotype.Component;

import javax.websocket.OnClose;
import javax.websocket.OnError;
import javax.websocket.OnOpen;
import javax.websocket.Session;
import javax.websocket.server.ServerEndpoint;
import java.io.IOException;
import java.util.*;

@Component
@Slf4j
@ServerEndpoint("/goods-ws")
public class WebSocketServerRecommend {
    @Autowired
    HotSearchMapper hotSearchMapper;
    @Autowired
    private WebSocketProperties webSocketProperties;

    private static List<String> RecommendedGoods = new ArrayList<>();
    private static Set<Session> sessions = new HashSet<>();

    @OnOpen
    public void onOpen(Session session) {
        sessions.add(session);
        log.info("WebSocket连接已建立 session: "+ session);
        // 手动获取service
        hotSearchMapper = SpringContextUtil.getBean(HotSearchMapper.class);
        webSocketProperties = SpringContextUtil.getBean(WebSocketProperties.class);
        sendRecommendedGoods();
    }

    @OnClose
    public void onClose(Session session) {
        // 连接关闭时的处理逻辑
    }

    @OnError
    public void onError(Session session, Throwable error) {
        // 错误处理逻辑
        error.printStackTrace();
    }

    /**
     * 发送推荐商品给所有客户端
     */
    private void sendRecommendedGoods() {
        try {
            String goodsList = String.join("\n", RecommendedGoods);
            log.info("WebSocket发送推荐商品给所有客户端: "+ goodsList);
            for (Session s : sessions){
                if (s.isOpen()){
                    s.getBasicRemote().sendText(goodsList);
                }
            }
        } catch (IOException e) {
            e.printStackTrace();
        }
    }

    /**
     * 定时更新推荐商品
     */
    @Scheduled(cron = "0 */5 * * * *")
    public void updateRecommendedGoods() {
        List<HotSearch> allGoods = hotSearchMapper.findAll();
        if (allGoods.isEmpty()) {
            return;
        }
        //使用HashSet来存储已选取的热门搜索词，保证不重复
        Set<String> selectedGoodsSet = new HashSet<>();
        Random random = new Random();
        RecommendedGoods.clear();
        // 每次随机默认取5个商品，数量在yml可调整
        int numToSelect = webSocketProperties.getSearchBoxNumber();
        while (RecommendedGoods.size() < numToSelect && selectedGoodsSet.size() < allGoods.size()) {
            //生成一个随机整数，作为从 allGoods 列表中选取元素的索引，确保生成的随机索引在 allGoods 列表的有效索引范围内
            int randomIndex = random.nextInt(allGoods.size());
            //通过上一步生成的随机索引 randomIndex，从 allGoods 列表中获取对应的 HotSearch 对象，将其赋值给 randomGoods 变量
            HotSearch randomGoods = allGoods.get(randomIndex);
            //用这个文本内容来判断是否重复
            String goodsText = randomGoods.getText();
            //检查 selectedGoodsSet 集合中是否已经包含了当前获取到的商品文本 goodsText
            if (!selectedGoodsSet.contains(goodsText)) {
                //如果上述条件为真，即当前商品文本还没有被选取过，就执行add语句，将该商品文本添加到 selectedGoodsSet 集合中，用于记录已经选取过这个商品
                selectedGoodsSet.add(goodsText);
                RecommendedGoods.add(goodsText);
            }
        }
        // 发送推荐商品给所有客户端
        sendRecommendedGoods();
    }

}
